<html>

<body onload="webGLStart();">

  <a href="http://sites.google.com/site/desarrolloenwebgl/tutorial-1/2---primer-programa">&lt;&lt; Volver a la leccion</a><br />
  <canvas id="Leccion1" style="border: none;" width="500" height="500"></canvas>
  <br/>
  <a href="http://sites.google.com/site/desarrolloenwebgl/tutorial-1/2---primer-programa">&lt;&lt; Volver a la leccion</a><br />

</body>

<head>

<title>Tecnologias Multimedia &mdash; Leccion 1</title>

<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">

<!-- Carga de los scripts necesarios para poder utilizar webGL y utilidades para el uso de matrices-->

<script type="text/javascript" src="sylvester.js"></script>
<script type="text/javascript" src="glUtils.js"></script>



<script type="text/javascript">

  function webGLStart() {


    var canvas = document.getElementById("Leccion1");

    initGL(canvas);

    initShaders();

    initBuffers();  <!-- Aqui cargamos el tipo de objetos que vamos a dibujar -->

    gl.clearColor(0.0, 0.0, 0.0, 1.0);

    gl.clearDepth(1.0);

    gl.enable(gl.DEPTH_TEST);

    gl.depthFunc(gl.LEQUAL);

    setInterval(drawScene, 15);

  }
    var gl;
    function initGL(canvas) {
<!--Obtenemos el contexto y los tamaños definidos para el canvas -->
        try {
            gl = canvas.getContext("experimental-webgl");
            gl.viewportWidth = canvas.width;
            gl.viewportHeight = canvas.height;
        } catch(e) {
        }
        <!-- Comprobamos que se ha podido inicializar correctamente -->
        if (!gl) {
        alert("Lo sentimos, no se ha podido inicializar webGL\n\nRevise la parte de configuraci�n de nuestro tutorial");
        }
    }

var triangleVertexPositionBuffer;
var squareVertexPositionBuffer;
 <!-- Funcion donde cargamos las estructuras que vamos a dibujar-->
    function initBuffers() {

        triangleVertexPositionBuffer = gl.createBuffer();                   <!-- Creamos el buffer -->
        gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer);       <!-- hacemos un bind, para asociar var con un determinado buffer -->
        var vertices = [                                                    <!-- Definimos los vertices del objeto -->
        <!--  X     Y     Z -->
            -1.0,  1.0,  0.0,
            -1.0, -1.0,  0.0,
             1.0, -1.0,  0.0
        ];

        <!-- Pasamos los datos al buffer, definiendo como estan formado el vector -->
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
        triangleVertexPositionBuffer.itemSize = 3;      <!-- Coordenadas -->
        triangleVertexPositionBuffer.numItems = 3;      <!-- Numero de vertices -->


        squareVertexPositionBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer);
        vertices = [
             1.0,  2.0,  0.0,
            -1.0,  1.0,  0.0,
             1.0, -2.0,  0.0,
            -1.0, -1.0,  0.0
        ];
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
        squareVertexPositionBuffer.itemSize = 3;
        squareVertexPositionBuffer.numItems = 4;
    }


  function getShader(gl, id) {
    var shaderScript = document.getElementById(id);
    if (!shaderScript) {
      return null;
    }

    var str = "";
    var k = shaderScript.firstChild;
    while (k) {
      if (k.nodeType == 3) {
        str += k.textContent;
      }
      k = k.nextSibling;
    }

    var shader;
    if (shaderScript.type == "x-shader/x-fragment") {
      shader = gl.createShader(gl.FRAGMENT_SHADER);
    } else if (shaderScript.type == "x-shader/x-vertex") {
      shader = gl.createShader(gl.VERTEX_SHADER);
    } else {
      return null;
    }

    gl.shaderSource(shader, str);
    gl.compileShader(shader);

    if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
      alert(gl.getShaderInfoLog(shader));
      return null;
    }

    return shader;
  }

  var mvMatrix;

  function loadIdentity() {
    mvMatrix = Matrix.I(4);
  }


  function multMatrix(m) {
    mvMatrix = mvMatrix.x(m);
  }


  function mvTranslate(v) {
    var m = Matrix.Translation($V([v[0], v[1], v[2]])).ensure4x4();
    multMatrix(m);
  }


  var pMatrix;
  function perspective(fovy, aspect, znear, zfar) {
    pMatrix = makePerspective(fovy, aspect, znear, zfar);
  }


  function setMatrixUniforms() {
    gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, new Float32Array(pMatrix.flatten()));
    gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, new Float32Array(mvMatrix.flatten()));
  }


<!-- Funcion que define la escena a dibujar -->

  function drawScene() {

    <!-- Definimos una vista, con su tamaño, y la "limpiamos" -->
    gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);


    <!-- Definimos una perspectiva (para que los objetos tengan profunidad) y decidimos -->
    <!-- hasta que profundidad max y minima queremos representar -->
    perspective(45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0);

    loadIdentity();

    <!-- situamos el "puntero" en un lugar del espacio-->
    mvTranslate([-1.5, 0.0, -7.0]);

    <!-- Seleccionamos el objeto y dibujamos el objeto en la posicion que este el "puntero" -->
    gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer);
    gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, triangleVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
    setMatrixUniforms();
    gl.drawArrays(gl.TRIANGLES, 0, triangleVertexPositionBuffer.numItems);


    <!-- situamos el "puntero" en un nuevo lugar del espacio-->
    <!-- los movimientos son relativos al sitio anterior -->
    mvTranslate([2.0, 0.0, 0.0]);

    <!-- Seleccionamos el objeto y dibujamos el objeto en la posicion que este el "puntero" -->
    gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer);
    gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, squareVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
    setMatrixUniforms();
    gl.drawArrays(gl.TRIANGLE_STRIP, 0, squareVertexPositionBuffer.numItems);
  }



    <!-- Funcion encargada de inicializar los shaders -->
    var shaderProgram;
    function initShaders() {
        var fragmentShader = getShader(gl, "shader-fs");
        var vertexShader = getShader(gl, "shader-vs");

        shaderProgram = gl.createProgram();
        gl.attachShader(shaderProgram, vertexShader);
        gl.attachShader(shaderProgram, fragmentShader);
        gl.linkProgram(shaderProgram);

        if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
            alert("Could not initialise shaders");
        }

        gl.useProgram(shaderProgram);

        shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram,"aVertexPosition");
        gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);

        shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
        shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
    }

var pvMatrixInverse = $M([0,0,0,0]);
var pvMatrix = $M([0,0,0,0]);
var eye = $V([0,0,0]);


function handleMouseUp(event) {

      var world1 = [0,0,0,0] ;
      var world2 = [0,0,0,0] ;
      var dir = [0,0,0] ;
      var w = event.srcElement.clientWidth ;
      var h = event.srcElement.clientHeight ;
      // calculate x,y clip space coordinates
      var x = (event.offsetX-w/2)/(w/2) ;
      var y = -(event.offsetY-h/2)/(h/2) ;

      //mat4.inverse(pvMatrix, pvMatrixInverse) ;
      pvMatrixInverse = inverse(pvMatrix) ;

      // convert clip space coordinates into world space
      //mat4.multiplyVec4(pvMatrixInverse, [x,y,-1,1], world1) ;
      world1=pvMatrixInverse.multiplyVec4([x,y,-1,1]);
      //vec3.scale(world1,1/world1[3]) ;
      world1=world1.x(1/world1[3]);

      //mat4.multiplyVec4(pvMatrixInverse, [x,y,0,1], world2) ;
      world2=pvMatrixInverse.multiplyVec4([x,y,-1,1]);
      //vec3.scale(world2,1/world2[3]) ;
      world2=world2.x(1/world2[3]);

      // calculate world space view vector
      //vec3.subtract(world2,world1,dir) ;
      dir=world2.subtract(world1);



      dir = normalize(dir);

      //vec3.scale(dir,0.3) ;
      dir=dir.x(0.3);
      // move eye in direction of world space view vector
      //vec3.subtract(eye,dir) ;
      eye=eye.x(dir);

      drawScene();
      console.log(event)
  }



</script>


<script id="shader-fs" type="x-shader/x-fragment">

  #ifdef GL_ES

  precision highp float;

  #endif



  void main(void) {

    gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);

  }

</script>



<script id="shader-vs" type="x-shader/x-vertex">

  attribute vec3 aVertexPosition;



  uniform mat4 uMVMatrix;

  uniform mat4 uPMatrix;



  void main(void) {

    gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);

  }

</script>



</head>



</html>